#include "gd32w51x.h"
#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "DevicesDock.h"


void vDockInit(void)
{
    /* enable the gpio clock */
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_GPIOB);
    /* enable the CFGCMP clock */
    rcu_periph_clock_enable(RCU_SYSCFG);

    /* configure pin as input */
    gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12);
    gpio_mode_set(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);

    /* enable and set EXTI interrupt to the specified priority */
    nvic_irq_enable(EXTI10_15_IRQn, 0, 0);
    nvic_irq_enable(EXTI1_IRQn, 0, 0);
    nvic_irq_enable(EXTI2_IRQn, 0, 0);
    nvic_irq_enable(EXTI3_IRQn, 0, 0);

    /* connect key EXTI line to GPIO pin */
    syscfg_exti_line_config(EXTI_SOURCE_GPIOA, EXTI_SOURCE_PIN10);
    syscfg_exti_line_config(EXTI_SOURCE_GPIOA, EXTI_SOURCE_PIN11);
    syscfg_exti_line_config(EXTI_SOURCE_GPIOA, EXTI_SOURCE_PIN12);
    syscfg_exti_line_config(EXTI_SOURCE_GPIOB, EXTI_SOURCE_PIN1);
    syscfg_exti_line_config(EXTI_SOURCE_GPIOB, EXTI_SOURCE_PIN2);
    syscfg_exti_line_config(EXTI_SOURCE_GPIOB, EXTI_SOURCE_PIN3);

    /* configure EXTI line */
    exti_init(EXTI_10, EXTI_INTERRUPT, EXTI_TRIG_RISING);
    exti_init(EXTI_11, EXTI_INTERRUPT, EXTI_TRIG_RISING);
    exti_init(EXTI_12, EXTI_INTERRUPT, EXTI_TRIG_RISING);
    exti_init(EXTI_1, EXTI_INTERRUPT, EXTI_TRIG_RISING);
    exti_init(EXTI_2, EXTI_INTERRUPT, EXTI_TRIG_RISING);
    exti_init(EXTI_3, EXTI_INTERRUPT, EXTI_TRIG_RISING);

    exti_interrupt_flag_clear(EXTI_10);
    exti_interrupt_flag_clear(EXTI_11);
    exti_interrupt_flag_clear(EXTI_12);
    exti_interrupt_flag_clear(EXTI_1);
    exti_interrupt_flag_clear(EXTI_2);
    exti_interrupt_flag_clear(EXTI_3);
}


int8_t cDockDecode(DockCodeType *ptypeData, int16_t sValue)
{
    uint8_t ucValue = 0;

    if((sValue > DOCK_CODE_LOW_MIN) && (sValue < DOCK_CODE_LOW_MAX))
        ucValue = 0;
    else if((sValue > DOCK_CODE_HIGH_MIN) && (sValue < DOCK_CODE_HIGH_MAX))
        ucValue = 1;
    else
        ptypeData->state = dockReset;

    ++ptypeData->length;

    switch(ptypeData->state)
    {
        case dockReset:
            memset(ptypeData, 0, sizeof(DockCodeType));
            ptypeData->state = dockReadUser;
            break;

        case dockReadUser:
            ptypeData->user = (ptypeData->user << 1) | ucValue;
            if(ptypeData->length >= 4)
                ptypeData->state = dockSucceed;
            break;

        default: ptypeData->state = dockReadUser; break;
    }

    if(ptypeData->state == dockSucceed)
        printf("length: %d, user: %02X\r\n", ptypeData->length, ptypeData->user);

    return ptypeData->state;
}

